package com.web.cms.pan.service;

import com.blue.core.dict.OperateType;
import com.blue.core.dict.State;
import com.blue.core.util.BeanUtil;
import com.blue.jdbc.JdbcDataSource;
import com.blue.jdbc.Page;
import com.web.cms.pan.dao.*;
import com.web.cms.pan.exception.FileDataException;
import com.web.cms.pan.exception.FolderException;
import com.web.cms.pan.model.FileData;
import com.web.cms.pan.model.Folder;
import com.web.cms.pan.model.FolderFile;
import com.web.cms.pan.model.OperatorLog;
import com.web.core.dict.PanExternalType;
import com.web.core.util.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 文件数据业务层
 * 
 * @author 代码由 blue-code 框架生成
 * @since 1.0 2018年04月09日
 */
@Service("panFileDataService")
@Transactional
@JdbcDataSource(Const.DS_CMS)
public class FileDataService
{
	@Autowired
	private FileDataDao fileDataDao;
	@Autowired
	private FolderFileDao folderFileDao;
	@Autowired
	private FolderDao folderDao;
	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private OperatorLogDao operatorLogDao;
	
	public FileDataService()
	{
	}
	
	public void add(FileData fileData, Integer userId, Integer folderId)
	{
		if (folderId > 0)
		{
			Folder folder = folderDao.get(folderId);
			if (folder == null)
				throw new FolderException("目录ID不存在：" + folderId);
			if (!userId.equals(folder.getUserId()))
				throw new FolderException("目录不与用户关联：" + userId);
		}

		fileData.setCount(1);
		fileDataDao.save(fileData);

		FolderFile folderFile = new FolderFile();
		folderFile.setFolderId(folderId);
		folderFile.setFileDataId(fileData.getId());
		folderFile.setUserId(userId);
		folderFile.setName(fileData.getName());
		folderFile.setKey(fileData.getKey());
		folderFile.setFileSize(fileData.getSize());
		folderFile.setType(fileData.getType());
		folderFileDao.save(folderFile);

		folderDao.inc(folderId, "files", 1, "fileSize", fileData.getSize());
		userInfoDao.inc(userId, "files", 1, "fileSize", fileData.getSize());
		operatorLogDao.add(userId, "上传文件：" + folderFile.getName(),
				folderFile.getId(), PanExternalType.FILE, OperateType.ADD);
	}

	public void update(FolderFile folderFile)
	{
		FolderFile ff = folderFileDao.get(folderFile.getId());
		if (ff == null)
			throw new FileDataException("文件不存在：" + folderFile.getId());
		if (!ff.getUserId().equals(folderFile.getUserId()))
			throw new FileDataException("文件不与用户关联：" + folderFile.getUserId());

		folderFileDao.updateObject(folderFile.getId(), "name", folderFile.getName());
		operatorLogDao.add(folderFile.getUserId(), "更新文件：" + folderFile.getName(),
				folderFile.getId(), PanExternalType.FILE, OperateType.UPDATE);
	}

	public void state(FolderFile folderFile)
	{
		FolderFile ff = folderFileDao.get(folderFile.getId());
		if (ff == null)
			throw new FileDataException("文件不存在：" + folderFile.getId());
		if (!ff.getUserId().equals(folderFile.getUserId()))
			throw new FileDataException("文件不与用户关联：" + folderFile.getUserId());

		Date now = (folderFile.getState() == State.DELETE ? new Date() : null);
		folderFileDao.updateObject(folderFile.getId(), "state", folderFile.getState().getIndex(), "deleteTime", now);
		operatorLogDao.add(folderFile.getUserId(), String.format("更新文件[%s]状态：%s", ff.getName(), folderFile.getState().getName()),
				ff.getId(), PanExternalType.FILE, OperateType.UPDATE);
	}
	
	public List<FolderFile> listFolderFile(FolderFile folderFile)
	{
		List<FolderFile> list = folderFileDao.list(folderFile);
		return list;
	}

	public Page<FileData> list(FileData fileData, Page<FileData> page)
	{
		page = fileDataDao.list(fileData, page);
		return page;
	}
	
	public void delete(Integer userId, List<Integer> ids)
	{
		Date now = new Date();
		Map<Integer, FolderFile> map = folderFileDao.getList(ids);
		Set<Integer> idSet = new HashSet<>();
		List<OperatorLog> logList = new ArrayList<>();

		int files = 0;
		int fileSize = 0;
		for (Map.Entry<Integer, FolderFile> entry : map.entrySet())
		{
			FolderFile ff = entry.getValue();
			if (!userId.equals(ff.getUserId()))
				throw new FileDataException("文件不与用户关联：" + ff.getUserId());

			idSet.add(ff.getId());
			logList.add(operatorLogDao.create(userId, "删除文件：" + ff.getName(), now, ff.getId(), PanExternalType.FILE, OperateType.DELETE));
			files++;
			fileSize += ff.getFileSize().intValue();
		}

		folderFileDao.deleteById(ids);
		userInfoDao.inc(userId, "files", -files, "fileSize", -fileSize, "deleteFiles", files, "deleteFileSize", fileSize);
		operatorLogDao.saveList(logList);
	}

	public void move(Integer userId, int folderFileId, int folderId)
	{
		FolderFile folderFile = this.check(userId, folderFileId, folderId);

		folderFileDao.updateObject(folderFileId, "folderId", folderId);
		folderDao.inc(folderFile.getFolderId(), "files", -1, "fileSize", -folderFile.getFileSize());
		if (folderId > 0)
		{
			folderDao.inc(folderId, "files", 1, "fileSize", folderFile.getFileSize());
		}
		operatorLogDao.add(folderFile.getUserId(), "移动文件：" + folderFile.getName(),
				folderFile.getId(), PanExternalType.FILE, OperateType.UPDATE);
	}

	public void copy(Integer userId, int folderFileId, int folderId)
	{
		FolderFile folderFile = this.check(userId, folderFileId, folderId);

		FolderFile ff = BeanUtil.createBean(FolderFile.class, folderFile);
		ff.setFolderId(folderId);
		folderFileDao.save(ff);

		fileDataDao.inc(folderFile.getFileDataId(), "count", 1);
		userInfoDao.inc(userId, "files", 1, "fileSize", folderFile.getFileSize());
		if (folderId > 0)
		{
			folderDao.inc(folderId, "files", 1, "fileSize", folderFile.getFileSize());
		}
		operatorLogDao.add(folderFile.getUserId(), "复制文件：" + folderFile.getName(),
				folderFile.getId(), PanExternalType.FILE, OperateType.UPDATE);
	}

	private FolderFile check(Integer userId, int folderFileId, int folderId)
	{
		FolderFile folderFile = folderFileDao.get(folderFileId);
		if (folderFile == null)
			throw new FileDataException("文件不存在：" + folderFileId);

		if (!userId.equals(folderFile.getUserId()))
			throw new FileDataException("文件不与用户关联：" + userId);

		if (folderId > 0)
		{
			Folder folder = folderDao.get(folderId);
			if (folder == null)
				throw new FolderException("目录不存在：" + folderId);

			if (!userId.equals(folder.getUserId()))
				throw new FolderException("目录不与用户关联：" + userId);
		}

		return folderFile;
	}
	
}
